/*
 * Vec4.h
 *
 *  Created on: 21.09.2009
 *      Author: Christoph Caks
 */

#ifndef VEC4_H_
#define VEC4_H_

#include "System.h"
#include "Math.h"
#include "types/Vec3.h"

namespace mehari {
namespace common {

template < typename Real >
class Vec4 {
public:
	// constructors
	Vec4();
	Vec4( const Vec3<Real>& v3Val, const Real w );
	Vec4( const Real x, const Real y, const Real z, const Real w );
	Vec4( const Vec4<Real>& v );


	~Vec4();

	// access
	Real x() const;
	Real& x();
	Real y() const;
	Real& y();
	Real z() const;
	Real& z();
	Real w() const;
	Real& w();
	const Real operator [] ( int iIndex ) const;
	Real& operator [] ( int iIndex );

	// arithmetic operations
	Vec4<Real> operator + ( const Vec4<Real>& vRhs ) const;
	Vec4<Real> operator - ( const Vec4<Real>& vRhs ) const;
	Vec4<Real> operator * ( const Real rRhs ) const;
	Vec4<Real> operator / ( const Real rRhs ) const;
	Vec4<Real> operator - () const;

	Vec4<Real> operator += ( const Vec4<Real>& vRhs );
	Vec4<Real> operator -= ( const Vec4<Real>& vRhs );
	Vec4<Real> operator *= ( const Real rRhs );
	Vec4<Real> operator /= ( const Real rRhs );

	// comparison operations
	bool operator == ( const Vec4<Real>& vRhs) const;
	bool operator != ( const Vec4<Real>& vRhs) const;
	bool operator <  ( const Vec4<Real>& vRhs) const;
	bool operator <= ( const Vec4<Real>& vRhs) const;
	bool operator >  ( const Vec4<Real>& vRhs) const;
	bool operator >= ( const Vec4<Real>& vRhs) const;

	// geometric operatons
	Real length() const;
	Real squaredLength() const;
	Real normalize();
	Real dot( const Vec4<Real>& vRhs ) const;
	Vec4<Real> cross( const Vec4<Real>& v4V ) const;
	Vec4<Real> unitCross( const Vec4<Real>& v4V ) const;

private:
	/**
	 * holds the data
	 * 0
	 * 1
	 * 2
	 * 3
	 */
	Real data[4];
};

template <typename Real>
Vec4<Real> operator * ( const Real rLhs, const Vec4<Real> vRhs ) {
	return Vec4<Real>( rLhs * vRhs.x(), rLhs * vRhs.y(), rLhs * vRhs.z(), rLhs * vRhs.w() );
}

#include "../../src/types/Vec4.cpp.inl"

typedef Vec4<float> Vec4f;
typedef Vec4<double> Vec4d;

} // namespace common
} // namespace mehari



#endif /* VEC4_H_ */
